<template>
    <div class="app-container">
        <div class="filter-container">
            <el-input
                v-model="listQuery.title"
                placeholder="Title"
                style="width: 200px"
                class="filter-item"
                @keyup.enter.native="handleFilter"
            />
            <el-select
                v-model="listQuery.importance"
                placeholder="Imp"
                clearable
                style="width: 90px"
                class="filter-item"
            >
                <el-option
                    v-for="item in importanceOptions"
                    :key="item"
                    :label="item"
                    :value="item"
                />
            </el-select>
            <el-select
                v-model="listQuery.type"
                placeholder="Type"
                clearable
                class="filter-item"
                style="width: 130px"
            >
                <el-option
                    v-for="item in calendarTypeOptions"
                    :key="item.key"
                    :label="item.display_name + '(' + item.key + ')'"
                    :value="item.key"
                />
            </el-select>
            <el-select
                v-model="listQuery.sort"
                style="width: 140px"
                class="filter-item"
                @change="handleFilter"
            >
                <el-option
                    v-for="item in sortOptions"
                    :key="item.key"
                    :label="item.label"
                    :value="item.key"
                />
            </el-select>
            <el-button
                v-waves
                class="filter-item"
                type="primary"
                icon="el-icon-search"
                @click="handleFilter"
            >
                搜索
            </el-button>
            <el-button
                class="filter-item"
                style="margin-left: 10px"
                type="primary"
                icon="el-icon-edit"
                @click="handleCreate"
            >
                添加
            </el-button>
            <el-button
                v-waves
                :loading="downloadLoading"
                class="filter-item"
                type="primary"
                icon="el-icon-download"
                @click="handleDownload"
            >
                导出
            </el-button>
            <el-checkbox
                v-model="showReviewer"
                class="filter-item"
                style="margin-left: 15px"
                @change="tableKey = tableKey + 1"
            >
                审核人
            </el-checkbox>
        </div>

        <el-table
            :key="tableKey"
            v-loading="listLoading"
            :data="list"
            border
            fit
            highlight-current-row
            style="width: 100%"
            @sort-change="sortChange"
        >
            <el-table-column
                label="ID"
                prop="id"
                sortable="custom"
                align="center"
                width="80"
                :class-name="getSortClass('id')"
            >
                <template slot-scope="{ row }">
                    <span>{{ row.id }}</span>
                </template>
            </el-table-column>
            <el-table-column label="日期" width="150px" align="center">
                <template slot-scope="{ row }">
                    <span>{{
                        row.timestamp | parseTime("{y}-{m}-{d} {h}:{i}")
                    }}</span>
                </template>
            </el-table-column>
            <el-table-column label="标题" min-width="150px">
                <template slot-scope="{ row }">
                    <span class="link-type" @click="handleUpdate(row)">{{
                        row.title
                    }}</span>
                </template>
            </el-table-column>
            <el-table-column label="来源" min-width="100px">
                <template slot-scope="{ row }">
                    <el-tag>{{ row.type | typeFilter }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column label="作者" width="110px" align="center">
                <template slot-scope="{ row }">
                    <span>{{ row.author }}</span>
                </template>
            </el-table-column>
            <el-table-column
                v-if="showReviewer"
                label="审核人"
                width="110px"
                align="center"
            >
                <template slot-scope="{ row }">
                    <span style="color: red">{{ row.reviewer }}</span>
                </template>
            </el-table-column>
            <el-table-column label="Imp" width="80px">
                <template slot-scope="{ row }">
                    <svg-icon
                        v-for="n in +row.importance"
                        :key="n"
                        icon-class="star"
                        class="meta-item__icon"
                    />
                </template>
            </el-table-column>
            <el-table-column label="阅读量" align="center" width="95">
                <template slot-scope="{ row }">
                    <span
                        v-if="row.pageviews"
                        class="link-type"
                        @click="handleFetchPv(row.pageviews)"
                        >{{ row.pageviews }}</span
                    >
                    <span v-else>0</span>
                </template>
            </el-table-column>
            <el-table-column label="状态" class-name="status-col" width="100">
                <template slot-scope="{ row }">
                    <el-tag :type="row.status | statusFilter">
                        {{ row.status }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column
                label="操作"
                align="center"
                width="230"
                class-name="small-padding fixed-width"
            >
                <template slot-scope="{ row, $index }">
                    <el-button
                        type="primary"
                        size="mini"
                        @click="handleUpdate(row)"
                    >
                        编辑
                    </el-button>
                    <el-button
                        v-if="row.status != 'published'"
                        size="mini"
                        type="success"
                        @click="handleModifyStatus(row, 'published')"
                    >
                        发行
                    </el-button>
                    <el-button
                        v-if="row.status != 'draft'"
                        size="mini"
                        @click="handleModifyStatus(row, 'draft')"
                    >
                        草稿
                    </el-button>
                    <el-button
                        v-if="row.status != 'deleted'"
                        size="mini"
                        type="danger"
                        @click="handleDelete(row, $index)"
                    >
                        删除
                    </el-button>
                </template>
            </el-table-column>
        </el-table>

        <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="listQuery.page"
            :limit.sync="listQuery.limit"
            @pagination="getList"
        />

        <el-dialog
            :title="textMap[dialogStatus]"
            :visible.sync="dialogFormVisible"
        >
            <el-form
                ref="dataForm"
                :rules="rules"
                :model="temp"
                label-position="left"
                label-width="70px"
                style="width: 400px; margin-left: 50px"
            >
                <el-form-item label="Type" prop="type">
                    <el-select
                        v-model="temp.type"
                        class="filter-item"
                        placeholder="Please select"
                    >
                        <el-option
                            v-for="item in calendarTypeOptions"
                            :key="item.key"
                            :label="item.display_name"
                            :value="item.key"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="Date" prop="timestamp">
                    <el-date-picker
                        v-model="temp.timestamp"
                        type="datetime"
                        placeholder="Please pick a date"
                    />
                </el-form-item>
                <el-form-item label="Title" prop="title">
                    <el-input v-model="temp.title" />
                </el-form-item>
                <el-form-item label="Status">
                    <el-select
                        v-model="temp.status"
                        class="filter-item"
                        placeholder="Please select"
                    >
                        <el-option
                            v-for="item in statusOptions"
                            :key="item"
                            :label="item"
                            :value="item"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="Imp">
                    <el-rate
                        v-model="temp.importance"
                        :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
                        :max="3"
                        style="margin-top: 8px"
                    />
                </el-form-item>
                <el-form-item label="Remark">
                    <el-input
                        v-model="temp.remark"
                        :autosize="{ minRows: 2, maxRows: 4 }"
                        type="textarea"
                        placeholder="Please input"
                    />
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false"> 取消 </el-button>
                <el-button
                    type="primary"
                    @click="
                        dialogStatus === 'create' ? createData() : updateData()
                    "
                >
                    保存
                </el-button>
            </div>
        </el-dialog>

        <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
            <el-table
                :data="pvData"
                border
                fit
                highlight-current-row
                style="width: 100%"
            >
                <el-table-column prop="key" label="Channel" />
                <el-table-column prop="pv" label="Pv" />
            </el-table>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="dialogPvVisible = false"
                    >保存</el-button
                >
            </span>
        </el-dialog>
    </div>
</template>

<script>
    import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
    import waves from '@/directive/waves' // waves directive
    import { parseTime } from '@/utils'
    import Pagination from '@/components/Pagination' // secondary package based on el-pagination
    import { sendGetRequest, sendPostRequest } from '@/request/request'

    const calendarTypeOptions = [
      { key: 'CN', display_name: 'China' },
      { key: 'US', display_name: 'USA' },
      { key: 'JP', display_name: 'Japan' },
      { key: 'EU', display_name: 'Eurozone' }
    ]

    // arr to obj, such as { CN : "China", US : "USA" }
    const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
      acc[cur.key] = cur.display_name
      return acc
    }, {})

    export default {
      name: 'ComplexTable',
      components: { Pagination },
      directives: { waves },
      filters: {
        statusFilter(status) {
          const statusMap = {
            published: 'success',
            draft: 'info',
            deleted: 'danger'
          }
          return statusMap[status]
        },
        typeFilter(type) {
          return calendarTypeKeyValue[type]
        }
      },
      data() {
        return {
          tableKey: 0,
          list: null,
          total: 0,
          listLoading: true,
          listQuery: {
            page: 1,
            limit: 20,
            importance: '',
            title: '',
            type: '',
            sort: '+id'
          },
          importanceOptions: [1, 2, 3],
          calendarTypeOptions,
          sortOptions: [
            { label: 'ID Ascending', key: '+id' },
            { label: 'ID Descending', key: '-id' }
          ],
          statusOptions: ['published', 'draft', 'deleted'],
          showReviewer: false,
          temp: {
            id: undefined,
            importance: 1,
            remark: '',
            timestamp: new Date(),
            title: '',
            type: '',
            status: 'published'
          },
          dialogFormVisible: false,
          dialogStatus: '',
          textMap: {
            update: 'Edit',
            create: 'Create'
          },
          dialogPvVisible: false,
          pvData: [],
          rules: {
            type: [{ required: true, message: 'type 必填', trigger: 'change' }],
            timestamp: [
              {
                type: 'date',
                required: true,
                message: 'timestamp 必填',
                trigger: 'change'
              }
            ],
            title: [{ required: true, message: 'title 必填', trigger: 'blur' }]
          },
          downloadLoading: false
        }
      },
      created() {
        this.getList()
      },
      methods: {
        getList() {
          this.listLoading = true
          sendGetRequest(fetchList(), this.listQuery).then(response => {
            //   fetchList(this.listQuery).then(response => {
            this.list = response.data.items
            this.total = response.data.total

            // Just to simulate the time of the request
            setTimeout(() => {
              this.listLoading = false
            }, 1.5 * 1000)
          })
        },
        handleFilter() {
          this.listQuery.page = 1
          this.getList()
        },
        handleModifyStatus(row, status) {
          this.$message({
            message: '操作Success',
            type: 'success'
          })
          row.status = status
        },
        sortChange(data) {
          const { prop, order } = data
          if (prop === 'id') {
            this.sortByID(order)
          }
        },
        sortByID(order) {
          if (order === 'ascending') {
            this.listQuery.sort = '+id'
          } else {
            this.listQuery.sort = '-id'
          }
          this.handleFilter()
        },
        resetTemp() {
          this.temp = {
            id: undefined,
            importance: 1,
            remark: '',
            timestamp: new Date(),
            title: '',
            status: 'published',
            type: ''
          }
        },
        handleCreate() {
          this.resetTemp()
          this.dialogStatus = 'create'
          this.dialogFormVisible = true
          this.$nextTick(() => {
            this.$refs['dataForm'].clearValidate()
          })
        },
        createData() {
          this.$refs['dataForm'].validate(valid => {
            if (valid) {
              this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
              this.temp.author = 'admin'
              sendPostRequest(createArticle(), this.temp).then(() => {
                this.list.unshift(this.temp)
                this.dialogFormVisible = false
                this.$notify({
                  title: 'Success',
                  message: '创建成功',
                  type: 'success',
                  duration: 2000
                })
              })
            }
          })
        },
        // 编辑
        handleUpdate(row) {
          // 复制原对象
          this.temp = Object.assign({}, row) // copy obj
          this.temp.timestamp = new Date(this.temp.timestamp)
          this.dialogStatus = 'update'
          this.dialogFormVisible = true
          //   移除表单的校验结果
          this.$nextTick(() => {
            this.$refs['dataForm'].clearValidate()
          })
        },
        // 编辑后的保存更新
        updateData() {
          this.$refs['dataForm'].validate(valid => {
            if (valid) {
              const tempData = Object.assign({}, this.temp)

              tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
              sendPostRequest(updateArticle(), tempData).then(() => {
                // 更新表单数据 找到下标位置
                const index = this.list.findIndex(v => v.id === this.temp.id)
                // 替换
                this.list.splice(index, 1, this.temp)
                this.dialogFormVisible = false
                this.$notify({
                  title: 'Success',
                  message: '更新成功',
                  type: 'success',
                  duration: 2000
                })
              })
            }
          })
        },
        handleDelete(row, index) {
          this.$notify({
            title: 'Success',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          this.list.splice(index, 1)
        },
        handleFetchPv(pv) {
          fetchPv(pv).then(response => {
            this.pvData = response.data.pvData
            this.dialogPvVisible = true
          })
        },
        handleDownload() {
          this.downloadLoading = true
          import('@/vendor/Export2Excel').then(excel => {
            const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
            const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
            const data = this.formatJson(filterVal)
            excel.export_json_to_excel({
              header: tHeader,
              data,
              filename: 'table-list'
            })
            this.downloadLoading = false
          })
        },
        formatJson(filterVal) {
          return this.list.map(v =>
            filterVal.map(j => {
              if (j === 'timestamp') {
                return parseTime(v[j])
              } else {
                return v[j]
              }
            })
          )
        },
        getSortClass: function(key) {
          const sort = this.listQuery.sort
          return sort === `+${key}` ? 'ascending' : 'descending'
        }
      }
    }
</script>

